using System.Xml.Serialization.Advanced;
using System.Xml.Serialization;
using System.CodeDom.Compiler;
using System.Xml.Schema;
using System.CodeDom;
using System.Collections;

namespace XWsdl {
    public class GenericSchemaImporterExtension: SchemaImporterExtension {
        /**************************************************************/
        /*                          Private
        /**************************************************************/
        private static string[] importNamespaces = new string[0];
        private static string datasetNamespace = "http://tempuri.org/dataset/";
        
        private static string datasetPrefixNamespace = "http://tempuri.org/";
        private static string datasetPostfixNamespace = ".xsd";

        private static bool useDefaultCriteraForDatasetNamespace;

        private static bool excludeArrayList;

        private static ArrayList types = new ArrayList();


        /**************************************************************/
        /*                          Public
        /**************************************************************/

        public override string ImportSchemaType(XmlSchemaType type, XmlSchemaObject context, XmlSchemas schemas, XmlSchemaImporter importer, CodeCompileUnit compileUnit, CodeNamespace mainNamespace, CodeGenerationOptions options, CodeDomProvider codeProvider)
        {
            
            if (type != null)
            {
                foreach (XmlSchema schema in schemas)
                {
                    types.Add(@"Schema: " + schema.TargetNamespace);

                    string rootNamespace = GenericSchemaImporterExtension.datasetNamespace;

                    string targetNamespace = schema.TargetNamespace;

                    if (useDefaultCriteraForDatasetNamespace) {
                        if (((targetNamespace.StartsWith(datasetPrefixNamespace) && targetNamespace.EndsWith(datasetPostfixNamespace))))
                        {
                            //mainNamespace.Imports.Add(new CodeNamespaceImport(typeof(AClassInTheSameNamespaceAsTheClasses).Namespace));

                            return schema.Id;
                        }
                    }
                    else
                    {
                        if (targetNamespace.StartsWith(rootNamespace))
                        {
                            //mainNamespace.Imports.Add(new CodeNamespaceImport(typeof(AClassInTheSameNamespaceAsTheClasses).Namespace));

                            return schema.Id;
                        }
                    }
                }
            }

            return base.ImportSchemaType(type, context, schemas, importer, compileUnit, mainNamespace, options, codeProvider);
        }

        public override string ImportSchemaType(string name, string ns,XmlSchemaObject context, XmlSchemas schemas,
            XmlSchemaImporter importer, CodeCompileUnit compileUnit, CodeNamespace codeNamespace,
            CodeGenerationOptions options, CodeDomProvider codeGenerator)
        {

            types.Add(@"Types: " +name + " " + ns);

            if (excludeArrayList)
            {
                if (IsBaseType(name, ns))
                {
                    return base.ImportSchemaType(name, ns, context, schemas, importer,
                        compileUnit, codeNamespace, options, codeGenerator);
                }

                // Add the Namespace, except the first
                for (int i = 1; i < ImportNamespaces.Length; i++)
                {
                    string _Import = ImportNamespaces[i];
                    codeNamespace.Imports.Add(new CodeNamespaceImport(_Import));
                }

                return name;
            }
            else
                return base.ImportSchemaType(name, ns, context, schemas, importer, compileUnit, codeNamespace, options, codeGenerator);
        }
        
        private static bool IsBaseType(string aName, string aNamespace) {
            if (aNamespace == "http://www.w3.org/2001/XMLSchema") {
                return true;
            }
                        
            if (aName.StartsWith("ArrayOf"))
            {
                return true;
            }

         return false;
        }

        /**************************************************************/
        /*                          Properties
        /**************************************************************/
        public static string[] ImportNamespaces {
            get {
                return importNamespaces;
            }
            set {
                importNamespaces = value;
            }
        }

        public static string DataSetNamespaces
        {
            get
            {
                return datasetNamespace;
            }
            set
            {
                datasetNamespace = value;
            }
        }

        public static bool UseDefaultCriteraForDatasetNamespace
        {
            get
            {
                return useDefaultCriteraForDatasetNamespace;
            }
            set
            {
                useDefaultCriteraForDatasetNamespace = value;
            }
        }

        public static bool ExcludeArrayList
        {
            get
            {
                return excludeArrayList;
            }
            set
            {
                excludeArrayList = value;
            }
        }

        public static ArrayList Types
        {
            get
            {
                return types;
            }
        }
    }
}
